package com.tfr.webflux.controller;

import com.tfr.webflux.entity.User;
import com.tfr.webflux.service.UserService;
import com.tfr.webflux.utils.CheckUtil;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import javax.validation.Valid;

/**
 * @description:
 * @author: rain
 * @date: Created in 2021/12/7 18:59
 * @version:
 * @modified By:
 */
@RestController
@RequestMapping("/user")
public class UserController {

  private final UserService userService;

  public UserController(UserService userService) {
    this.userService = userService;
  }

  @GetMapping()
  public Flux<User> getAll() {
    return userService.findAll();
  }

  @GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
  public Flux<User> getAllStream() {
    return userService.findAll();
  }

  @PostMapping
  public Mono<User> saveUser(@Valid @RequestBody User user) {
    user.setId(null);
    CheckUtil.checkName(user.getName());
    return userService.save(user);
  }

  @DeleteMapping("/{id}")
  public Mono<ResponseEntity<Void>> del(@PathVariable String id) {
    //    return userService.deleteById(id);
    return userService
        .findById(id)
        .flatMap(
            user ->
                userService.delete(user).then(Mono.just(new ResponseEntity<Void>(HttpStatus.OK))))
        .defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
  }

  @PutMapping("/{id}")
  public Mono<ResponseEntity<User>> update( @PathVariable String id,@Valid @RequestBody User user) {
    return userService
        .findById(id)
        .flatMap(
            u -> {
              u.setAge(user.getAge());
              u.setName(user.getName());
              return userService.save(u);
            })
        .map(u -> new ResponseEntity<User>(u, HttpStatus.OK))
        .defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
  }

  @GetMapping("/{id}")
  public Mono<ResponseEntity<User>> findById(@PathVariable String id) {
    return userService
        .findById(id)
        .map(u -> new ResponseEntity<User>(u, HttpStatus.OK))
        .defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
  }

  @GetMapping("/age")
  public Flux<User> findByAge(int start, int end) {
    return userService.findByAgeBetween(start, end);
  }
}
